package org.example.mock;

import com.github.javafaker.Faker;
import org.example.bean.BookInfo;

import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class BookInfoDataGenerator {
    private static final String DB_URL = "jdbc:mysql://hadoop102/bookstore?useSSL=false&requireSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "000000";
    private static final int BATCH_SIZE = 100;
    private static final Faker faker = new Faker(Locale.CHINA);

    public static void main(String[] args) {
        int count = 1; // 默认生成50条数据
        if (args.length >= 1) count = Integer.parseInt(args[0]);
        generateData(count);
    }

    public static void generateData(int count) {
        List<BookInfo> books = new ArrayList<>();

        for (int i = 0; i < count; i++) {
            LocalDateTime now = LocalDateTime.now();
            BookInfo book = BookInfo.builder()
                    .bookId("B" + String.format("%08d", faker.number().numberBetween(10000000, 99999999)))
                    .bookName(faker.book().title())
                    .author(faker.book().author())
                    .publisher(faker.company().name() + "出版社")
                    .publishDate(LocalDate.now().minusYears(faker.number().numberBetween(1, 10)))
                    .categoryId("C" + String.format("%03d", faker.number().numberBetween(1, 20)))
                    .categoryName(faker.options().option("科幻", "文学", "计算机", "历史", "童书", "经济", "教育"))
                    .price(new java.math.BigDecimal(String.valueOf(faker.number().numberBetween(20, 300))))
                    .price(java.math.BigDecimal.valueOf(faker.number().randomDouble(2, 20, 300)))
                    .isbn(faker.code().isbn13())
                    .pageCount(faker.number().numberBetween(100, 500))
                    .wordCount(faker.number().numberBetween(50000, 300000))
                    .printTime(faker.number().numberBetween(1, 20))
                    .stockStatus(faker.number().numberBetween(0, 3))
                    .createTime(now)
                    .updateTime(now)
                    .build();

            books.add(book);
        }

        insertData(books);
    }

    private static void insertData(List<BookInfo> books) {
        String sql = "INSERT INTO book_info (book_id, book_name, author, publisher, publish_date, " +
                "category_id, category_name, price, cost, isbn, page_count, word_count, " +
                "print_time, stock_status, create_time, update_time) " +
                "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)";

        try (Connection conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD)) {
            conn.setAutoCommit(false);
            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                for (int i = 0; i < books.size(); i++) {
                    BookInfo book = books.get(i);
                    pstmt.setString(1, book.getBookId());
                    pstmt.setString(2, book.getBookName());
                    pstmt.setString(3, book.getAuthor());
                    pstmt.setString(4, book.getPublisher());
                    pstmt.setDate(5, java.sql.Date.valueOf(book.getPublishDate()));
                    pstmt.setString(6, book.getCategoryId());
                    pstmt.setString(7, book.getCategoryName());
                    pstmt.setBigDecimal(8, book.getPrice());
                    pstmt.setBigDecimal(9, book.getCost());
                    pstmt.setString(10, book.getIsbn());
                    pstmt.setInt(11, book.getPageCount());
                    pstmt.setInt(12, book.getWordCount());
                    pstmt.setInt(13, book.getPrintTime());
                    pstmt.setInt(14, book.getStockStatus());
                    pstmt.setTimestamp(15, Timestamp.valueOf(book.getCreateTime()));
                    pstmt.setTimestamp(16, Timestamp.valueOf(book.getUpdateTime()));
                    pstmt.addBatch();

                    if ((i + 1) % BATCH_SIZE == 0) pstmt.executeBatch();
                }
                pstmt.executeBatch();
                conn.commit();
                System.out.println("成功插入" + books.size() + "条图书数据");
            } catch (SQLException e) {
                conn.rollback();
                e.printStackTrace();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}